define(['polyfill','md5'],
    function (polyfill,md5) {
        var componentClassDict = {};
        var pageConfigDict = {};

        var colorMap = {};

        var translateKeys = null;
        var p;
        var Re = {
            AutoResizeImage: function (maxWidth, maxHeight, objImg, type) {

                var img = new Image();
                img.src = objImg.src;
                img.onload = function () {
                    var hRatio;
                    var wRatio;
                    var Ratio = 1;
                    var w = img.width;
                    var h = img.height;
                    wRatio = maxWidth / w;
                    hRatio = maxHeight / h;
                    if (maxWidth === 0 && maxHeight === 0) {
                        Ratio = 1;
                    } else if (maxWidth === 0) { //
                        if (hRatio < 1) Ratio = hRatio;
                    } else if (maxHeight === 0) {
                        if (wRatio < 1) Ratio = wRatio;
                    } else if (wRatio < 1 || hRatio < 1) {
                        Ratio = (wRatio <= hRatio ? wRatio : hRatio);
                    }
                    if (type === "1") {

                        if (Ratio < 1) {

                            if (w >= h) {
                                w = "auto";
                                h = "100%";

                            } else {
                                w = "100%";
                                h = "auto";
                            }

                        }
                        var size = {
                            w: (w === "100%" || w === "auto" ? w : w + "px"),
                            h: (h === "100%" || h === "auto" ? h : h + "px")
                        };
                        objImg.style.width = size.w;
                        objImg.style.height = size.h;

                    } else {
                        if (Ratio < 1) {
                            w = w * Ratio;
                            h = h * Ratio;
                        }
                        objImg.height = h;
                        objImg.width = w;
                    }

                };
            },

            deviceInfo: function () {
                if (this._deviceInfo !== undefined) {
                    return this._deviceInfo;
                }
                var u = navigator.userAgent;
                var isAndroid = u.indexOf('Android') > -1 || u.indexOf('Adr') > -1;
                var isIOS = !!u.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/); //ios终端
                this._deviceInfo = {
                    isAndroid: isAndroid,
                    isIOS: isIOS
                };
                return this._deviceInfo;
            },
            getPicSize: function (maxWidth, maxHeight, w, h) {
                var hRatio;
                var wRatio;
                var Ratio = 1;
                wRatio = maxWidth / w;
                hRatio = maxHeight / h;

                if (maxWidth === 0 && maxHeight === 0) {
                    Ratio = 1;
                } else if (maxWidth === 0) { //
                    if (hRatio < 1) Ratio = hRatio;
                } else if (maxHeight === 0) {
                    if (wRatio < 1) Ratio = wRatio;
                } else if (wRatio < 1 || hRatio < 1) {
                    Ratio = (wRatio <= hRatio ? wRatio : hRatio);
                }

                if (Ratio < 1) {

                    if (w >= h) {
                        w = "auto";
                        h = "100%";

                    } else {
                        w = "100%";
                        h = "auto";
                    }

                }

                return {
                    w: (w === "100%" || w === "auto" ? w : w + "px"),
                    h: (h === "100%" || h === "auto" ? h : h + "px")
                };
            },
            //返回标准时区时间
            convertStrToDate: function (str) {
                if (!str) {
                    return new Date();
                }
                var str_arr = str.split(" ");
                var yearmonthday = str_arr[0];
                var hourminsecond = str_arr[1] || "";
                var hourminsecond_arr = hourminsecond.split(":");
                var yearmonthday_arr = yearmonthday.split("-");
                if (yearmonthday_arr.length != 3) {
                    yearmonthday_arr = yearmonthday.split("/");
                }
                if (yearmonthday_arr.length != 3) {
                    return new Date();
                }
                if (!hourminsecond) {
                    return new Date(yearmonthday_arr[0], parseInt(yearmonthday_arr[1]) - 1, yearmonthday_arr[2]);
                }
                return new Date(yearmonthday_arr[0], parseInt(yearmonthday_arr[1]) - 1, yearmonthday_arr[2], hourminsecond_arr[0] || 0, hourminsecond_arr[1] || 0, hourminsecond_arr[2] || 0);

            },
            getPreMonth: function (date) {
                var dateInfo = this.getDateInfo(date);
                var nextMonth = new Date(dateInfo.year, dateInfo.month - 1, 0);
                return nextMonth;
            },
            getCurMonthFirstDay: function (date) {
                date = this.convertToDate(date);
                var dateInfo = this.getDateInfo(date);
                return new Date(dateInfo.year, dateInfo.month - 1, 1);
            },
            getPreYear: function (date) {
                var dateInfo = this.getDateInfo(date);
                var preYear = new Date(dateInfo.year - 1, dateInfo.month - 1, 1);
                return preYear;
            },
            compareDate: function (date1, date2) {
                date1 = this.ConvertDateToStr(date1, "yyyy-MM-dd");
                date2 = this.ConvertDateToStr(date2, "yyyy-MM-dd");
                date1 = this.convertToDate(date1);
                date2 = this.convertToDate(date2);
                if (date1 > date2) {
                    return 1;
                }
                if (date1 - date2 === 0) {
                    return 0;
                }
                return -1;
            },
            compareDateToDay: function (date1, date2) {
                //比较精确到天,返回相差天数
                var dayTimeStamp = 1000*60*60*24;
                date1 = this.ConvertDateToStr(date1, "yyyy-MM-dd");
                date2 = this.ConvertDateToStr(date2, "yyyy-MM-dd");
                date1 = parseInt(this.convertToDate(date1).getTime() / dayTimeStamp);
                date2 = parseInt(this.convertToDate(date2).getTime() / dayTimeStamp);
                return date1-date2;
            },
            setDateToYear: function (date, year) {
                var dateInfo = this.getDateInfo(date);
                var preYear = new Date(year, dateInfo.month - 1, 1);
                return preYear;
            },
            setMonthToDate: function (date, month) {
                month = parseInt(month);
                var dateInfo = this.getDateInfo(date);
                return new Date(dateInfo.year, month - 1, 1);
            },
            getNextYear: function (date) {
                var dateInfo = this.getDateInfo(date);
                var nextYear = new Date(dateInfo.year + 1, dateInfo.month - 1, 1);
                return nextYear;
            },
            getNextMonth: function (date) {
                var dateInfo = this.getDateInfo(date);
                var nextMonth = new Date(dateInfo.year, dateInfo.month + 1, 0);
                return nextMonth;
            },
            getMonthFirstDayWhicDayInWeek: function (date) {
                date = this.convertToDate(date);
                var d = new Date(date.getFullYear(), date.getMonth(), 1);
                return d.getDay();
            },
            //根据formart转换成相应格式
            ConvertDateToStr: function (date, formart) {
                date = this.convertToDate(date);
                var info = this.getDateInfo(date);
                info.month = info.month < 10 ? "0" + info.month : info.month;
                info.day = info.day < 10 ? "0" + info.day : info.day;
                info.min = info.min < 10 ? "0" + info.min : info.min;
                info.second = info.second < 10 ? "0" + info.second : info.second;
                info.hour = info.hour < 10 ? "0" + info.hour : info.hour;
                if (formart == "yyyy-MM-dd") {
                    return info.year + "-" + info.month + "-" + info.day;
                } else if (formart == "yyyy-MM") {
                    return info.year + "-" + info.month;
                } else if (formart == "yyyy-MM-dd hh:mm:ss") {
                    return info.year + "-" + info.month + "-" + info.day + " " + info.hour + ":" + info.min + ":" + info.second;
                } else if (formart == "MM-dd hh:mm") {
                    return info.month + "-" + info.day + " " + info.hour + ":" + info.min;
                } else if (formart == "hh:mm") {
                    return info.hour + ":" + info.min;
                } else if (formart == "MM-dd week") {
                    return info.month + "-" + info.day + " " + info.week;
                } else if (formart == "yyyy-MM-dd week") {
                    return info.year + "-" + info.month + "-" + info.day + " " + info.week;
                } else if (formart == "yyyy-MM-dd hh:mm") {
                    return info.year + "-" + info.month + "-" + info.day + " " + info.hour + ":" + info.min;
                }else if(formart == "yyyyMMdd week hh:mm"){
                    return info.year + "年" + info.month + "月" + info.day + "日" + info.week + " " + info.hour + ":" + info.min;
                }
                return info.year + "-" + info.month + "-" + info.day;
            },
            //转换成年月日
            ConverStampToText: function (date) {
                date = this.convertToDate(date);
                var info = this.getDateInfo(date);
                info.month = info.month < 10 ? "0" + info.month : info.month;
                info.day = info.day < 10 ? "0" + info.day : info.day;
                return info.year + "年" + info.month + "月" + info.day + "日";
            },
            getMonthDayCount: function (date) {
                date = this.convertToDate(date);
                var newDate = new Date(date.getFullYear(), date.getMonth() + 1, 0);
                return newDate.getDate();
            },
            convertToDate: function (date) {
                try {
                    if (date instanceof Date) {
                        return date;
                    } else if (!isNaN(date)) {
                        return this.timestampToDate(date);
                    } else if (typeof(date) == "string") {
                        return this.convertStrToDate(date);
                    }
                } catch (e) {
                    return new Date();
                }

                return new Date();


            },
            _processtime: function (num) {
                return (num < 10 ? ("0" + num) : num);
            },
            isJSON: function (obj) {
                var isjson = typeof(obj) == "object" && Object.prototype.toString.call(obj)
                    .toLowerCase() == "[object object]" && !obj.length;
                return isjson;
            },

            weekArr: ["日", "一", "二", "三", "四", "五", "六"],
            getDateInfo: function (date) {
                date = this.convertToDate(date);
                var month = date.getMonth() + 1;
                var day = date.getDate();
                var hour = date.getHours();
                var min = date.getMinutes();
                var second = date.getSeconds();
                var week = date.getDay();
                return {
                    year: date.getFullYear(),
                    month: month,
                    weekStr: this.weekArr[week],
                    weekFullStr: "星期" + this.weekArr[week],
                    week: "周" + this.weekArr[week],
                    monthStr: this._processtime(month),
                    day: day,
                    dayStr: this._processtime(day),
                    hour: hour,
                    hourStr: this._processtime(hour),
                    min: min,
                    minStr: this._processtime(min),
                    second: second,
                    secondStr: this._processtime(second)
                };
            },
            viewport: {
                width: null,
                height: null
            },

            getImgBg: function (str) {
                str = str || '';
                if (str in colorMap) return colorMap[str];

                var c = md5(str).charAt(0).toLowerCase();
                var color = ['#29d4ff', '#1594ff', '#ffa92f', '#b587fa', '#06cf86', '#fa6771', '#73d51c', '#8991ff'];
                var bg = color['abcdefghijklmnopqrstuvwxyz0123456789'.indexOf(c) % color.length];

                colorMap[str] = bg;
                return bg;
            },
            getImgTitle: function (str) {
                try {
                    str = str || '';
                    return /[\u4e00-\u9fa5]/.test(str) ? str.substr(-2) : str.substr(0, 2);
                } catch (e) {
                    return str;
                }

            },

            deleteEmoji: function (str) {
                return str.replace(/\uD83C[\uDF00-\uDFFF]|\uD83D[\uDC00-\uDE4F]/g, "");
            },
            addDay: function (date, count) {
                date = this.convertToDate(date);
                return new Date(date.setDate(date.getDate() + count)); //获取AddDayCount天后的日期
            },


            getUrl: function (url) {
                if (url.indexOf("http") >= 0 || url.indexOf("https") >= 0) {
                    return url;
                }
                if (url.indexOf("//") === 0) {
                    url = url.substring(1, url.length);
                    return url;
                }
                // 其他host枚举
                var otherHosts = ['taskHost',''];
                var firstPath = '/' + url.split('/')[1];

                for (var i = 0; i < otherHosts.length; i++) {
                    if (this.appConfig[otherHosts[i]] && (firstPath === this.appConfig[otherHosts[i]])) {
                        return url;
                    }
                }

                var host = this.appConfig.host;
                if (!host) {
                    console.error("请在app.js中指定host属性");
                }

                host = $.trim(host);
                url = $.trim(url);
                if (host.substring(host.length - 1) == "/") {
                    host = host.substring(0, host.length - 1);
                }
                if (url.substring(0, 1) == "/") {
                    url = url.substring(1);
                }

                return host + "/" + url;
            },
            //秒转换成小时分钟
            secondToTime: function(seconds){
                var h = seconds/3600;
                var m = (seconds%3600)/60;
                return parseInt(h)+"小时"+parseInt(m)+"分钟";
            },
            timestampToDate: function (timestamp) {
                if (!timestamp) return new Date();

                // 特殊处理php时间戳
                if (timestamp.toString().length === 10) {
                    timestamp = timestamp * 1000;
                }
                return new Date(parseInt(timestamp));
            },
            timestampToDateInfo: function (timestamp) {
                var date;
                try {
                    timestamp = parseFloat(timestamp);
                    date = new Date(timestamp);
                } catch (e) {
                    date = new Date();
                }
                return this.getDateInfo(date);

            },
            timestampToTimeStr: function (timestamp) {
                var Re = "";
                try {
                    timestamp = parseInt(timestamp);
                    if(timestamp.toString().length===10){
                        timestamp = timestamp*1000;
                    }
                    var date = new Date(timestamp);
                    var now = new Date();
                    var time = now.getTime();
                    var dateInfo = this.getDateInfo(date);
                    var nowDateInfo = this.getDateInfo(now);
                    if(timestamp.toString().length>10){
                        time = parseInt((time - timestamp) / 1000);
                    }else{
                        time = parseInt((time - timestamp));
                    }
                    var s;
                    if (time < 60 * 1) {
                        Re = '刚刚';
                    } else if ((time < 60 * 60) && (time >= 60 * 1)) {
                        s = Math.floor(time / 60);
                        Re = s + "分钟前";
                    } else if (nowDateInfo.year === dateInfo.year && nowDateInfo.day === dateInfo.day && nowDateInfo.month === dateInfo.month) {
                        Re = "今天 " + dateInfo.hourStr + ":" + dateInfo.minStr;
                    } else if (nowDateInfo.year === dateInfo.year) {
                        Re = dateInfo.monthStr + "-" + dateInfo.dayStr + " " + dateInfo.hourStr + ":" + dateInfo.minStr;
                    } else {
                        Re = dateInfo.year + "-" + dateInfo.monthStr + "-" + dateInfo.dayStr + " " + dateInfo.hourStr + ":" + dateInfo.minStr;
                    }
                } catch (e) {

                }
                return Re;
            },
            toNow: function (t) {
                t = (new Date() - new Date(t))/1000;
                if(t < 0) return '';
                var year = 3600*24*360,
                    month = 3600*24*30,
                    day = 3600*24,
                    hour = 3600,
                    minute = 60;
                if(t > year) {
                    return ~~(t/year) + '年前';
                } else if(t > month) {
                    return ~~(t/month) + '个月前';
                } else if(t > day) {
                    return ~~(t/day) + '天前';
                } else if(t > hour) {
                    return ~~(t/hour) + '小时前';
                } else if(t > minute) {
                    return ~~(t/minute) + '分钟前';
                } else {
                    return ~~t + '秒前';
                }
            },
            processHTMLMethod2: function (str) {
                var test = $("<div></div>");
                test.html(str);
                var imageDoms = test.find("img");

                var originalText = test.html();

                imageDoms.replaceWith("");
                var curText = test.text();

                return {
                    originalText: originalText,
                    imageDoms: imageDoms,
                    curText: curText
                };
            },
            clone: function (json) {
                var json_str = JSON.stringify(json);
                return JSON.parse(json_str);
            },
            processHTML: function (str, callback) {
                var test = $("<div></div>");
                test.html(str);
                var imageDoms = test.find("img");

                var originalText = test.html();

                var cloneDom = $("<div></div>");
                cloneDom.html(str);

                var cloneDoms = cloneDom.find("img");

                if (callback) {
                    callback(cloneDoms);
                }

                imageDoms.replaceWith("[图片]");
                var curText = test.text();

                return {
                    dom: cloneDom,
                    originalText: originalText,
                    imageDoms: imageDoms,
                    curText: curText
                };
            },
            createStyleSheet: function (id, str) {
                if (document.getElementById(id)) {
                    return;
                }
                var style = document.createElement('style');
                style.type = 'text/css';
                style.id = id;
                style.innerHTML = str;
                document.getElementsByTagName('head')[0].appendChild(style);
            },
            getDaysArrInCanledar: function (date) {
                var Re = [];
                var monthDayCount = this.getMonthDayCount(date);
                var monthInfo = this.getDateInfo(date);
                var firstDayWhichDayInWeek = this.getMonthFirstDayWhicDayInWeek(date);
                var nextMonthCount = (6 * 7) - firstDayWhichDayInWeek - monthDayCount;
                var i = 0;
                if (firstDayWhichDayInWeek > 0) {
                    var preMonth = this.getPreMonth(date);
                    var preMonthLastDay = this.getMonthDayCount(preMonth);
                    var preMonthInfo = this.getDateInfo(preMonth);
                    for (i = 0; i < firstDayWhichDayInWeek; i++) {
                        var day = (preMonthLastDay - firstDayWhichDayInWeek + i + 1);
                        date = new Date(preMonthInfo.year, preMonthInfo.month - 1, day);
                        Re.push({
                            date: date,
                            dateStr: this.ConvertDateToStr(date),
                            year: preMonthInfo.year,
                            month: preMonthInfo.month,
                            day: day,
                            mark: "premonth"
                        });
                    }
                }
                for (i = 1; i <= monthDayCount; i++) {
                    date = new Date(monthInfo.year, monthInfo.month - 1, i);
                    Re.push({
                        date: date,
                        dateStr: this.ConvertDateToStr(date),
                        year: monthInfo.year,
                        month: monthInfo.month,
                        day: i,
                        mark: "curmonth"
                    });
                }
                if (nextMonthCount > 0) {

                    var nextMonth = this.getNextMonth(date);
                    var nextMonthInfo = this.getDateInfo(nextMonth);
                    for (i = 1; i <= nextMonthCount; i++) {
                        date = new Date(nextMonthInfo.year, nextMonthInfo.month - 1, i);
                        Re.push({
                            date: date,
                            dateStr: this.ConvertDateToStr(date),
                            year: nextMonthInfo.year,
                            month: nextMonthInfo.month,
                            day: i,
                            mark: "nextmonth"
                        });
                    }
                }
                return Re;
            },
            ajax: function (config) {
                var _this = this;
                var pageviewInstance = config.pageviewInstance;
                config.data = config.data || {};
                var beforeSendAjax = _this.appConfig.beforeSendAjax;
                if (beforeSendAjax) {
                    beforeSendAjax(config);
                }
                var responseMethod = _this.appConfig.onAjaxResponse;
                $.support.cors = true;
                var ajaxConfig = {
                    type: config.type,
                    crossDomain: true,
                    url: this.getUrl(config.url),
                    timeout: config.timeout || 8000,
                    data: config.data,
                    success: function (data) {
                        if (responseMethod) {
                            responseMethod({
                                isSuccess: true,
                                data: data,
                                config: config
                            });
                        }
                        if (config.success) {
                            config.success(data);
                        }
                    },
                    error: function (e) {
                        if (responseMethod) {
                            responseMethod({
                                isSuccess: false,
                                e: e,
                                config: config,
                                data: {
                                    code: -1000,
                                    msg: "服务器错误"
                                }
                            });
                        }
                        if (config.error) {
                            config.error(e);
                        }
                    }
                };
                if (config.contentType) {
                    ajaxConfig.contentType = config.contentType;
                    ajaxConfig.dataType = "json";
                } else {
                    ajaxConfig.contentType = "application/x-www-form-urlencoded";
                }
                if (this.isIE()) {
                    this.crossDomainAjax(ajaxConfig);
                } else {
                    $.ajax(ajaxConfig);
                }

            },
            crossDomainAjax: function (ajaxOption) {
                var xhr = '';
                var _ajaxOption = ajaxOption;

                if (window.XMLHttpRequest) { // code for all new browsers
                    xhr = new XMLHttpRequest();
                } else if (window.ActiveXObject) { // code for IE5 and IE6
                    xhr = new ActiveXObject("Microsoft.XMLHTTP");
                }
                try {
                  if (xhr !== null) {
                      xhr.onreadystatechange = state_Change;
                      var para = '';
                      if (ajaxOption.data && !$.isEmptyObject(ajaxOption.data) && ajaxOption.contentType.indexOf('application/json') === -1) {
                          $.each(ajaxOption.data, function (key, value) {
                              // 给字段增加编码
                              para += key + '=' + encodeURIComponent(value) + '&';
                          });
                      } else if ($.isEmptyObject(ajaxOption.data)) {
                          // 参数为空时类型不能传obj
                          para = '';
                      } else {
                          para = ajaxOption.data;
                      }

                      if (ajaxOption.type === 'GET') {
                          para = '&' + para;
                          var url = ajaxOption.url + para;
                          xhr.open('GET', url, true);
                          xhr.send();
                      } else if (ajaxOption.type === 'POST') {
                          xhr.open('POST', ajaxOption.url, true);
                          xhr.setRequestHeader("Content-Type", ajaxOption.contentType || "application/x-www-form-urlencoded");
                          xhr.send(para);
                      } else if (ajaxOption.type === 'DELETE') {
                          xhr.open('DELETE', ajaxOption.url, true);
                          xhr.setRequestHeader("Content-Type", ajaxOption.contentType || "application/x-www-form-urlencoded");
                          xhr.send(para);
                          console.log('send success');
                      }
                  } else {
                      alert("Your browser does not support XMLHTTP.");
                  }


                } catch (e) {
                  console.log(e);
                } finally {

                }

                function state_Change() {
                    if (xhr.readyState === 4) { // 4 = "loaded"
                        try {
                            var data = $.parseJSON(xhr.responseText);
                            _ajaxOption.success(data);
                        } catch (e) {
                            console.error(e);
                        }
                    }
                }
            },
            concat: function (baseConfig, part, namespace) {
                if (!namespace) {
                    console.error("合并页面配置的时候没有指定namespace");
                }
                baseConfig.components = baseConfig.components || {};
                for (var key in part) {
                    var real_key = namespace + key;
                    if (baseConfig.components[real_key]) {
                        console.error(real_key + " 已经存在原有的页面中 请不要重复控件的Key");
                    }
                    var com_config = part[key];
                    var com_root = com_config.root;
                    if (com_root) {
                        for (var i = 0, j = com_root.length; i < j; i++) {
                            com_root[i] = namespace + com_root[i];
                        }
                    }
                    baseConfig.components[real_key] = part[key];
                }
                return baseConfig;
            },


            setPageConfigByPagePath: function (pagePath, pageConfig) {

                pageConfigDict[pagePath] = pageConfig;
                return pageConfig;
            },
            getPageConfigByPagePath: function (pagePath) {
                return pageConfigDict[pagePath];
            },
            getComponentInstance: function (com_type) {
                return componentClassDict[com_type];
            },
            customerComponents: {},
            getComponentClass: function (config, success, error) {
                var type = config.type;
                var com_class = componentClassDict[type];
                if (com_class) {
                    success(com_class);
                    return;
                }
                var com_path = Re.customerComponents[type];

                if (com_path) {

                } else {
                    com_path = "../../components/" + type;
                }
                require([com_path],
                    function (comClass) {
                        //只require一次再起请求是从缓存栈里取
                        componentClassDict[type] = comClass;
                        success(comClass);
                    },
                    function () {
                        error(config);
                    });

            },
            css: function (com, cssobj, isAdapte) {
                if (!cssobj) {
                    return;
                }
                com.css(cssobj);
            },
            simpleExtendObj: function (obj1, obj2) {
                obj1 = obj1 || {};
                obj2 = obj2 || {};
                for (var key in obj2) {
                    obj1[key] = obj2[key];
                }
                return obj1;
            },
            processTransitionStyle: function (transition) {
                return {
                    transition: transition,
                    "-webkit-transition": transition
                };
            },
            processTransformStyle: function (transform) {
                return {
                    transform: transform,
                    "-webkit-transform": transform
                };
            },

            isIE: function () {
                if (!!window.ActiveXObject || "ActiveXObject" in window) {
                    return true;
                }
                return false;
            },
            isBadIE:function(){
                if(!this.isIE()){
                    return false;
                }
                var browser = navigator.appName;
                var b_version = navigator.appVersion;
                var version = b_version.split(";");
                if (version.length > 1) {
                   var trim_Version = parseInt(version[1].replace(/[ ]/g, "").replace(/MSIE/g, ""));
                   if (trim_Version < 9) {
                       return true;
                   }
               }
               return false;
            },

            _browserInfo: null,
            browserInfo: function () {
                if (this._browserInfo !== null) {
                    return this._browserInfo;
                }
                var browserName = navigator.userAgent.toLowerCase();
                this._browserInfo = {
                    isQQ: /qqbrowser/i.test(browserName),
                    isFirfox: /firefox/i.test(browserName),
                    isIE: this.isIE()
                };
                return this._browserInfo;
            },
            _isNeedReLayout: null,
            isNeedReLayout: function () {
                if (this._isNeedReLayout !== null) {
                    return this._isNeedReLayout;
                }
                var browserInfo = this.browserInfo();
                return browserInfo.isIE || browserInfo.isQQ || browserInfo.isFirfox;
            },

            //transition:"transform .2s ease",transform:"translate3d(0,0,0)"
            processTransitionTanformStyle: function (transition, transform) {
                return {
                    transition: transition,
                    "-webkit-transition": transition,
                    transform: transform,
                    "-webkit-transform": transform
                };
            },
            copy: function (from, to) {
                // http://stackoverflow.com/questions/122102/what-is-the-most-efficient-way-to-clone-an-object-in-javascript
                if (from === null || from === undefined || typeof from != "object") return from;
                if (from.constructor != Object && from.constructor != Array) return from;
                if (from.constructor == Date || from.constructor == RegExp || from.constructor == Function || from.constructor == String || from.constructor == Number || from.constructor == Boolean) return new from.constructor(from);

                to = to || new from.constructor();

                for (var name in from) {
                    to[name] = typeof to[name] == "undefined" ? this.copy(from[name], null) : to[name];
                }

                return to;
            },
            extendClass: function (subClass, baseClass) {
                function inheritance() {}

                inheritance.prototype = baseClass.prototype;
                subClass.prototype = new inheritance();
                subClass.prototype.constructor = subClass;
                subClass.baseConstructor = baseClass;
                subClass.superClass = baseClass.prototype;
            }
        };
        return Re;
    });
